package syR

import (
	"encoding/json"
	"fmt"
	"db2s/global"
	"db2s/outPut"
	"db2s/pubM"
	"strings"
	"sync"
	"sync/atomic"
)

var newTer *outPut.Terminal
var newTextTPod outPut.FileOperations
var breakP pubM.BreakActionEr
var outputExecFunc = global.EFunc{
	FuncName: func(event string, s any) (r any) {
		var writeStr string
		if s == nil {
			return
		}
		p := tPodR(s)
		switch p.CheckMode {
		case "sync":
			if q, err := json.Marshal(global.CreateNewStruct(p, append(global.GetJSONFieldNames(p), "Sync"))); err != nil {
				return nil
			} else {
				writeStr = fmt.Sprintf("%v\n", string(q))
			}
		}
		if err := newTextTPod.Write("", writeStr); err != nil {
			return nil
		}
		if strings.EqualFold(p.Result, "ok") {
			if err := breakP.Write(fmt.Sprintf("%v.%v\n", p.Schema, p.Table)); err != nil {
				return nil
			}
		}
		return
	},
}

func podResultAction(r *outPut.TPod) *outPut.TPod {
	switch {
	case r.TableMiss:
		r.Result = "miss"
	case r.Result == "error":
	case r.Sync.SyncSum != nil && r.Sync.SelectRows != nil:
		if atomic.LoadInt64(r.Sync.SyncSum) != atomic.LoadInt64(r.Sync.SelectRows) {
			r.Result = "abnormal"
		}
	case r.Sync.InsertRows != nil && r.Sync.SelectRows != nil:
		if atomic.LoadInt64(r.Sync.InsertRows) != atomic.LoadInt64(r.Sync.SelectRows) {
			r.Result = "abnormal"
		}
	}
	return r
}
func tPodPar(pod any) (r any) {
	switch pod.(type) {
	case *outPut.TPod:
		r = pod.(*outPut.TPod)
	case outPut.TPod:
		l := pod.(outPut.TPod)
		r = &l
	case *outPut.WorkSheetTerminal:
		r = pod.(*outPut.WorkSheetTerminal)
	case outPut.WorkSheetTerminal:
		l := pod.(outPut.WorkSheetTerminal)
		r = &l
	}
	return
}
func tPodToPar(pod any, r any) (res any) {
	switch pod.(type) {
	case *outPut.TPod:
		res = *r.(*outPut.TPod)
	case *outPut.WorkSheetTerminal:
		res = *r.(*outPut.WorkSheetTerminal)
	case outPut.TPod, outPut.WorkSheetTerminal:
		res = r
	default:
		res = r
	}
	return
}

func xlsTPod(pod any) (res any) {
	switch pod.(type) {
	case *outPut.TPod:
		res = podResultAction(pod.(*outPut.TPod))
	case *outPut.WorkSheetTerminal:
		q := pod.(*outPut.WorkSheetTerminal)
		qq := podResultAction(&q.Data)
		q.Data = *qq
		res = q
	}
	return
}
func tPodResult(event string, pod any) (res any) {
	var r = tPodPar(pod)
	switch pod.(type) {
	case *outPut.TPod:
		r = xlsTPod(r.(*outPut.TPod))
	case *outPut.WorkSheetTerminal:
		r = xlsTPod(r.(*outPut.WorkSheetTerminal))
	default:
		r = pod
	}
	return tPodToPar(pod, r)
}
func tPodR(s any) (p outPut.TPod) {
	switch s.(type) {
	case outPut.TPod:
		p = s.(outPut.TPod)
	case *outPut.TPod:
		p = *(s.(*outPut.TPod))
	}
	return p
}
func terminal(wg *sync.WaitGroup) {
	var initContext = global.GetIoc().GetBean("schemaInitContext").(*SchemaInitContext)
	var sum = initContext.TableSum
	newTer = outPut.NewTerminal(outPut.Terminal{
		Wg:            wg,
		Mode:          GlobalPConfigs.rules.CheckMode,
		IgnoreSum:     initContext.IgnoreObjectSum,
		BreakPointSum: int64(len(continueTableList)),
		Pods:          make(chan any, global.ChannelDefault),
		ModifyValFunc: global.EFunc{FuncName: tPodResult},
		ExecFunc:      []global.EFunc{outputExecFunc},
	})
	newTer.Sum.Swap(sum)
	newTer.Start()
	newTer.Run()
}
